package plugins.buildjava.projecttype;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import domain.model.project.ProjectDeveloper;
import domain.model.project.ProjectType;
import infra.jenkins.JenkinsRule;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Gregory Boissinot
 */
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
public class JavaBuildProjectTypeImpl implements RWJavaBuildProjectTypeExtension {

    private static final String DEFAULT_JAVA_BUILD_TYPE_NAME = "buildjava";

    @JsonProperty(required = false)
    private List<ProjectDeveloper> projectDeveloperList = Collections.EMPTY_LIST;

    @JsonProperty(required = false)
    private String sourceCompatibility;

    @JsonProperty(required = false)
    private String targetCompatibility;

    @Override
    public List<ProjectDeveloper> getProjectDeveloperList() {
        return Collections.unmodifiableList(projectDeveloperList);
    }

    @Override
    public ProjectType copyWithProjectDevelopers(List<ProjectDeveloper> projectDevelopers) {
        return new JavaBuildProjectTypeBuilder()
                .projectDeveloperList(projectDevelopers)
                .build();
    }

    @Override
    @JsonIgnore
    public String getName() {
        return DEFAULT_JAVA_BUILD_TYPE_NAME;
    }

    @Override
    public String getSourceCompatibility() {
        return sourceCompatibility;
    }

    @Override
    public String getTargetCompatibility() {
        return targetCompatibility;
    }

    @Override
    public void setSourceCompatibility(String sourceCompatibility) {
        this.sourceCompatibility = sourceCompatibility;
    }

    @Override
    public void setTargetCompatibility(String targetCompatibility) {
        this.targetCompatibility = targetCompatibility;
    }

    @Override
    public void setProjectDeveloperList(List<ProjectDeveloper> projectDeveloperList) {
        this.projectDeveloperList = projectDeveloperList;
    }

    @JsonIgnore
    @Override
    public Map<String, Object> getMetaInformation() {
        Map<String, Object> mapInfo = new HashMap<String, Object>();
        mapInfo.put(JenkinsRule.JOB_EXTENSION, "JAR");
        return mapInfo;
    }

    @Override
    public boolean sameValueAs(ProjectType objectValue) {
        return equals(objectValue);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        JavaBuildProjectTypeImpl that = (JavaBuildProjectTypeImpl) o;

        if (projectDeveloperList != null ? !projectDeveloperList.equals(that.projectDeveloperList) : that.projectDeveloperList != null)
            return false;
        if (sourceCompatibility != null ? !sourceCompatibility.equals(that.sourceCompatibility) : that.sourceCompatibility != null)
            return false;
        if (targetCompatibility != null ? !targetCompatibility.equals(that.targetCompatibility) : that.targetCompatibility != null)
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = projectDeveloperList != null ? projectDeveloperList.hashCode() : 0;
        result = 31 * result + (sourceCompatibility != null ? sourceCompatibility.hashCode() : 0);
        result = 31 * result + (targetCompatibility != null ? targetCompatibility.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        final ReflectionToStringBuilder reflectionToStringBuilder = new ReflectionToStringBuilder(this,
                ToStringStyle.MULTI_LINE_STYLE);
        return reflectionToStringBuilder.toString();
    }
}
